# coding = utf-8
from app import app, db
from .models import User, Follow, Essay, Support
from flask import flash, render_template, redirect, url_for, request, session, jsonify, abort
from sqlalchemy.sql.expression import func
from .log import logging_by
import datetime
import os
import re
import random
import pytz

tz = pytz.timezone('Asia/Shanghai')


@app.errorhandler(404)
def internal_server_error(e):
    '''
    Avoid displaying error codes directly on the browser

    :param e: the exception
    :return: a error page
    '''
    return render_template('Error.html', code=404)


@app.errorhandler(500)
def internal_server_error(e):
    '''
    Avoid displaying error codes directly on the browser

    :param e: the exception
    :return: a error page
    '''
    return render_template('Error.html', code=500)


@app.route("/")
def root():
    return redirect(url_for('login'))


@app.route("/login", methods=["POST", "GET"])
def login():
    try:
        if request.method == "POST":
            user = db.session.query(User).filter_by(account=request.form.get("account"),
                                                    password_hash=request.form.get("md5_pwd"), isDelete=False).first()
            if user is not None:
                # login in success
                session['login'] = 'true'
                session['userid'] = user.userid
                session['account'] = request.form.get("account")
                logging = logging_by('login')
                logging.info(session['account'] + " is login.")
                mesg = url_for("person", user_id=user.userid)
                return jsonify({"code": 2, 'mesg': mesg})
            else:
                # return jsonify({"code": 1, 'mesg': "账号或密码错误"})
                return jsonify({"code": 1, 'mesg': "Wrong account or password"})
        return render_template("Title.html")
    except e:
        logging = logging_by('error')
        logging.info(e.msg)


@app.route("/sign", methods=["POST", "GET"])
def sign():
    try:
        if request.method == "POST":
            user = db.session.query(User).filter_by(account=request.form.get("account"), isDelete=False).first()
            if user is None:
                logging = logging_by('sign')
                now_time = datetime.datetime.now(tz)
                head_num = random.randint(1, 6)
                head = str(head_num) + ".png"
                user = User(account=request.form.get("account"), nickname=request.form.get("nickname"), head_pic=head,
                            password_hash=request.form.get("md5_pwd"), createTime=now_time, updateTime=now_time)
                db.session.add_all([user])
                db.session.commit()
                session['userid'] = user.userid
                session['account'] = request.form.get("account")
                session['nickname'] = request.form.get("nickname")
                session['login'] = 'true'
                logging.info(session['account'] + " is sign.")
                mesg = url_for("person", user_id=user.userid)
                return jsonify({"code": 2, 'mesg': mesg})
            else:
                # return jsonify({"code": 1, 'mesg': "手机号已被注册"})
                return jsonify({"code": 1, 'mesg': "The mobile phone number has been registered"})
        return render_template("sign.html")
    except e:
        logging = logging_by('error')
        logging.info(e.msg)


@app.route("/find_pwd", methods=["POST", "GET"])
def find_pwd():
    try:
        if request.method == "POST" and request.form.get("vcode") is None:
            user = db.session.query(User).filter_by(account=request.form.get("account"), isDelete=False).first()
            if user is None:
                # return "账号不存在"
                return "Account does not exist"
            else:
                return "1"
        elif request.method == "POST":
            user = db.session.query(User).filter_by(account=request.form.get("account"), isDelete=False).first()
            if validate_code(request.form.get("vcode")) is False:
                # flash("验证码错误")
                flash("Verification code error")
            else:
                logging = logging_by('login')
                session['account'] = request.form.get("account")
                session['login'] = 'true'
                session['userid'] = user.userid
                logging.info(session['account'] + " is login by vcode.")
                return redirect(url_for("person", user_id=user.userid))
        return render_template("fin_pwd.html")
    except e:
        logging = logging_by('error')
        logging.info(e.msg)


@app.route('/person/<user_id>', methods=["POST", "GET"])
def person(user_id):
    try:
        user_id = int(user_id)
        authority = 0
        if 'userid' not in session:
            authority = 0
        elif 'userid' not in session:
            authority = 0
        elif session['userid'] != user_id:
            authority = 1
        else:
            authority = 2
        user = db.session.query(User).filter_by(userid=user_id, isDelete=False).first()
        # 关注数量
        follower_count = db.session.query(Follow).filter_by(fanid=user.userid, isDelete=False).count()
        # 粉丝数量
        fan_count = db.session.query(Follow).filter_by(followerid=user.userid, isDelete=False).count()
        followers_list = db.session.query(Follow).filter_by(fanid=user.userid, isDelete=False).all()
        followers = []
        for follow in followers_list:
            follower = db.session.query(User).filter_by(userid=follow.followerid, isDelete=False).first()
            if follower is not None:
                followers.append(follower)

        if authority != 0:
            # essays = db.session.query(Essay, Support).outerjoin(Support, Support.essayid==Essay.essayid).\
            #     filter(Essay.authorid==user.userid, Essay.isDelete==False, Support.userid==session['userid']).\
            #     order_by(Essay.createTime.desc()).all()
            essays = db.session.query(Essay, Support).outerjoin(Support, Support.essayid==Essay.essayid). \
                filter(Essay.authorid==user.userid, Essay.isDelete==False). \
                order_by(Essay.createTime.desc()).all()

            eid = []
            for essay in essays:
                if essay[0].essayid not in eid:
                    eid.append(essay[0].essayid)
                elif essay[1].userid == session['userid']:
                    for e in essays:
                        if e[0].essayid == essay[0].essayid:
                            essays.remove(e)
                else:
                    essays.remove(essay)
        else:
            essays = db.session.query(Essay, Support).outerjoin(Support, Support.essayid==-1). \
                filter(Essay.authorid==user.userid, Essay.isDelete==False). \
                order_by(Essay.createTime.desc()).all()
        content = {}

        for essay in essays:
            essay = essay[0]
            lines = []
            f = open(essay.get_essay_url(), "r")
            line = f.readline()

            while line:
                lines.append(line)
                line = f.readline()
            content[essay.essayid] = lines
            f.close()
        data = {"user": user, "follower_count": follower_count, "fan_count": fan_count, "followers": followers,
                "essays": essays,
                "content": content}

        recommends = []
        if authority != 0:
            # user_id_list = User.query.join(Follow,Follow.fanid!=session['userid']).\
            #     filter(User.userid!=2, User.isDelete==False ,User.userid!=Follow.followerid).all()
            follow_id_list = db.session.query(Follow.followerid).\
                filter_by(fanid=session['userid'], isDelete=False).all()
            follow_id = []
            for i in follow_id_list:
                follow_id.append(i[0])
            user_id_list = db.session.query(User).\
                filter(User.userid!=2, User.isDelete==False, User.userid!=session['userid'],
                       User.userid.notin_(follow_id)).all()
            limit_count = 3
            if len(user_id_list) < 3:
                limit_count = len(user_id_list)

            recommends_users = random.sample(user_id_list, limit_count)

            for ru in recommends_users:
                recommends.append(db.session.query(User).filter_by(userid=ru.userid).first())

        admin = db.session.query(User).filter_by(userid=2).first()

        if 'userid' in session:
            data['c_userid'] = session['userid']

        if request.method == "POST":
            if request.form.get("content") != "":
                essay_content = request.form.get("content")
                # mesg = "成功"
                mesg = "success"
                add_essay(essay_content, user_id)
                return jsonify({"code": 0, 'mesg': mesg})
            else:
                # mesg = "失败"
                mesg = "Fail"
                return jsonify({"code": 1, 'mesg': mesg})
    except KeyError:
        abort(404)
        logging = logging_by('error')
        logging.info(e.msg)
    return render_template('person_page.html', data=data, authority=authority, title=user.nickname + "的主页",
                           bar_control=0, admin=admin, recommends=recommends)


@app.route("/logout")
def logout():
    logging = logging_by('logout')
    logging.info(session['account'] + " is logout.")
    session.clear()
    return redirect(url_for("login"))


@app.route("/delete/<essayid>")
def delete(essayid):
    try:
        now_time = datetime.datetime.now(tz)
        if 'userid' not in session:
            abort(404)
        essay = db.session.query(Essay).filter_by(essayid=essayid).first()
        if essay is not None:
            essay.delete_essay(now_time)
            db.session.commit()
            logging = logging_by('essay')
            logging.info(str(essay.essayid) + " is deleted.")
        return redirect(request.referrer)
    except e:
        logging = logging_by('error')
        logging.info(e.msg)


def add_essay(content, userid):
    try:
        BASE_DIR = os.path.dirname(os.path.abspath(__file__))
        now_time = datetime.datetime.now(tz)
        essay = Essay(authorid=userid, createTime=now_time, updateTime=now_time)
        db.session.add_all([essay])
        db.session.commit()
        essay_path = os.path.join(BASE_DIR, 'essay')
        essay_path = os.path.join(essay_path, str(essay.essayid))
        f = open(essay_path, 'w')
        f.write(content)
        f.close()
        logging = logging_by('essay')
        logging.info(str(essay.essayid) + " is added.")
        return essay
    except e:
        logging = logging_by('error')
        logging.info(e.msg)


@app.route('/follow/<user_id>', methods=["POST", "GET"])
def follow(user_id):
    try:
        user_id = int(user_id)
        authority = 0
        if 'userid' not in session:
            authority = 0
        elif session['userid'] != user_id:
            authority = 1
        else:
            authority = 2

        user = db.session.query(User).filter_by(userid=user_id, isDelete=False).first()
        # 关注数量
        follower_count = db.session.query(Follow).filter_by(fanid=user_id, isDelete=False).count()
        # 粉丝数量
        fan_count = db.session.query(Follow).filter_by(followerid=user_id, isDelete=False).count()
        followers_list = db.session.query(Follow).filter_by(fanid=user_id, isDelete=False).all()
        followers = []
        for follow in followers_list:
            follower = db.session.query(User).filter_by(userid=follow.followerid, isDelete=False).first()
            if follower is not None:
                followers.append(follower)
        fans_list = db.session.query(Follow).filter_by(followerid=user_id, isDelete=False).all()
        fans = []
        for follow in fans_list:
            fan = db.session.query(User).filter_by(userid=follow.fanid, isDelete=False).first()
            if fan is not None:
                fans.append(fan)
        ship = db.session.query(Follow).filter_by(followerid=user_id, fanid=session['userid'], isDelete=False).first()
        data = {"user": user, "follower_count": follower_count, "fan_count": fan_count, "followers": followers,
                "fans": fans}
        if 'userid' in session:
            data['c_userid'] = session['userid']
        if ship is None:
            data['isFollow'] = 0
        else:
            data['isFollow'] = 1
        if request.method == "POST":
            ac = request.form.get("content").replace(' ', '')
            ac = ac.replace("\n", "")
            friend = db.session.query(User).filter_by(account=ac, isDelete=False).first()
            if friend is not None:
                friend_info = {'account': friend.account, 'nickname': friend.nickname, 'head': friend.head_pic,
                               'userid': friend.userid}
                return jsonify({"code": 0, 'mesg': friend_info})
            else:
                # mesg = "查无此人"
                mesg = "There is no such person"
                return jsonify({"code": 1, 'mesg': mesg})
    except KeyError:
        abort(404)
        logging = logging_by('error')
        logging.info(e.msg)
    return render_template("follow.html", user_id=user_id, data=data, title=user.nickname + "的好友", authority=authority)


@app.route("/follow_it/<follower_id>")
def follow_it(follower_id):
    try:
        if 'userid' not in session:
            abort(404)
        now_time = datetime.datetime.now(tz)
        ship = db.session.query(Follow).filter_by(followerid=follower_id, fanid=session['userid']).first()
        logging = logging_by('follow')
        if ship is not None:
            ship.isDelete = False
            db.session.commit()
            logging.info("user id [" + str(ship.fanid) + "] follows user id [" + str(ship.followerid) + "].")
        else:
            follow = Follow(followerid=follower_id, fanid=session['userid'], createTime=now_time, updateTime=now_time)
            db.session.add_all([follow])
            db.session.commit()
            logging.info("user id [" + str(follow.fanid) + "] follows user id [" + str(follow.followerid) + "].")
        return redirect(url_for("follow", user_id=follower_id))
    except e:
        logging = logging_by('error')
        logging.info(e.msg)


@app.route("/not_follow/<follower_id>")
def not_follow(follower_id):
    try:
        if 'userid' not in session:
            abort(404)
        ship = db.session.query(Follow).filter_by(followerid=follower_id, fanid=session['userid']).first()
        logging = logging_by('follow')
        if ship is not None:
            ship.isDelete = True
            db.session.commit()
            logging.info("user id [" + str(ship.fanid) + "] does not follow user id [" + str(ship.followerid) + "].")
        return redirect(url_for("follow", user_id=follower_id))
    except e:
        logging = logging_by('error')
        logging.info(e.msg)


@app.route("/support/<essay_id>/<user_id>-<s>")
def support(essay_id, user_id, s):
    s = int(s)
    now_time = datetime.datetime.now(tz)
    if 'userid' not in session:
        abort(404)
    elif s is not 0 and s is not 1:
        abort(404)
    essay = db.session.query(Essay).filter_by(essayid=essay_id).first()

    if essay is not None:

        if s == 1:
            essay.get_support(session['userid'], now_time)
        elif s == 0:
            essay.not_support(session['userid'], now_time)
        db.session.commit()
    return redirect(url_for('person',user_id=user_id))


@app.route("/info/<user_id>", methods=['POST', 'GET'])
def info(user_id):
    try:
        now_time = datetime.datetime.now(tz)
        user_id = int(user_id)
        user = db.session.query(User).filter_by(userid=user_id).first()
        data = {'user': user, 'c_userid': user.userid}
        logging = logging_by('info')
        if request.method == "POST":
            if 'new_pwd' in request.form:
                user.password_hash = request.form.get("new_pwd")
                user.updateTime = now_time
                db.session.commit()
                logging.info("user id [" + str(user.userid) + "] changes password and nickname.")
                # return jsonify({"nickname": "修改成功", 'pwd': "修改成功"})
                return jsonify({"nickname": "Modified successfully", 'pwd': "Modified successfully"})
            else:
                user.nickname = request.form.get("nickname")
                user.updateTime = now_time
                db.session.commit()
                logging.info("user id [" + str(user.userid) + "] changes nickname.")
                # return jsonify({"nickname": "修改成功"})
                return jsonify({"nickname": "Modified successfully"})

        return render_template("info.html", user_id=user_id, data=data, bar_control=0)
    except e:
        logging = logging_by('error')
        logging.info(e.msg)


# 过滤器将时间格式化
@app.template_filter('time')
def time(t):
    tm = t.strftime("%Y-%m-%d, %H:%M:%S")
    return tm


def validate_code(code):
    if code == "991123":
        return True
    return False
